package org.hzero.system.str;

import io.choerodon.core.exception.CommonException;
import org.hzero.system.annotation.KnifeValidateStrLength;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @ClassName: ThStringUtil
 * @Description: 字符串工具
 * @author: tianhao.luo@hand-china.com
 * @date: 2020/11/30  10:21
 */
public final class KnifeStringUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(KnifeStringUtil.class);

    /**
     * 截断length的字符串
     *
     * @param str 被截断的字符串
     * @param length 指定长度
     * @return 截断后的字符串
     */
    public static String cutOffString(String str, int length) {
        if (!StringUtils.isEmpty(str)){
            byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
            int strLength = bytes.length;
            if (strLength > length) {
                byte[] bytes2 = Arrays.copyOf(bytes, length);
                String firstCutStr = new String(bytes2, StandardCharsets.UTF_8);
                //存在最后一个字节不是英文的情况，如果不是英文就会出现�乱码，所以要把最后那个乱码解决
                if (firstCutStr.getBytes(StandardCharsets.UTF_8).length>length){
                    return firstCutStr.replace("�","");

                }else {
                    return firstCutStr;
                }
            } else {
                return str;
            }
        }else {
            return "";
        }
    }


    /**
     * 校验对象中添加了KnifeValidateStrLength注解的字符串属性的长度
     * 响应信息例如：备注填写了481个字符，超过最大长度240限制，请精简后保存！
     * @param object 对象
     */
    public static void validateLength(Object object) {
        ArrayList<String> longStringColumns = new ArrayList<>();
        Class<?> aClass = object.getClass();
        ArrayList<Field> allFieldList = new ArrayList<>();
        // 添加所有有KnifeValidateStrLength注解的字段
        addKnifeValidateStrLengths(allFieldList,aClass);
        // 校验
        if (!CollectionUtils.isEmpty(allFieldList)){
            for (Field field : allFieldList) {
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                try {
                    String s = Optional.ofNullable(field.get(object)).orElse("").toString();
                    KnifeValidateStrLength annotation = field.getAnnotation(KnifeValidateStrLength.class);
                    if (s.length() > annotation.maxLength()){
                        String str = annotation.name() + "填写了"+s.length()+"个字符，超过最大长度" + annotation.maxLength() + "限制";
                        longStringColumns.add(str);
                    }
                } catch (IllegalAccessException e) {
                    LOGGER.error("反射查找字符串字段的长度出错！");
                }
            }
        }
        if (!CollectionUtils.isEmpty(longStringColumns)){
            throw new CommonException(String.join("；",longStringColumns)+"，请精简后保存!");
        }
    }

    /**
     * 扫描添加头字段
     *
     * @param fieldList 存储容器
     * @param aClass               头class
     */
    private static void addKnifeValidateStrLengths(List<Field> fieldList, Class<?> aClass) {
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            KnifeValidateStrLength annotation = declaredField.getAnnotation(KnifeValidateStrLength.class);
            if (annotation != null && "string".equalsIgnoreCase(declaredField.getType().getSimpleName())) {
                fieldList.add(declaredField);
            }
        }
        // 有父类
        Class<?> superclass = aClass.getSuperclass();
        if (superclass != null) {
            addKnifeValidateStrLengths(fieldList, superclass);
        }
    }
}
